package cn.com.git.example.module.api;

import cn.com.git.example.common.ResultConstant;
import cn.com.git.example.common.ResultMsg;
import cn.com.git.example.common.ResultPage;
import cn.com.git.example.common.auth.AuthenticationTokenDTO;
import cn.com.git.example.common.base.BaseApi;
import cn.com.git.example.common.entity.DataTree;
import cn.com.git.example.common.exception.ApiException;
import cn.com.git.example.common.util.object.JSONUtils;
import cn.com.git.example.config.manager.FileManager;
import cn.com.git.example.module.service.DemoService;
import cn.com.git.example.module.service.dto.DemoDTO;
import cn.com.git.example.module.service.dto.DemoSaveForm;
import cn.com.git.example.module.service.query.DemoListQuery;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@Slf4j
@Api(value = "示例", description = "示例的描述")
@RestController
@RequestMapping("/demo")
public class DemoApi extends BaseApi {
    @Autowired
    private DemoService demoService;
    @Autowired
    private FileManager fileManager;


    @ApiOperation(value = "hello 测试", notes = "测试的请求", httpMethod = "GET")
    @GetMapping(value = "/hello")
    public ResultMsg hello() {
        lock("demo_hello", () -> {
            System.out.println(JSONUtils.toJson(loginContext.getCurrentUser()));
            return null;
        });
        return new ResultMsg(ResultConstant.SUCCESS);
    }

    @ApiOperation(value = "exception 测试", notes = "测试的请求", httpMethod = "GET")
    @GetMapping(value = "/exception")
    public ResultMsg exception() {
        int i = 1 / 0;
        return new ResultMsg(ResultConstant.SUCCESS);
    }

    @ApiOperation(value = "列表查询", notes = "列表查询", httpMethod = "POST", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @PostMapping(value = "/list/page", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResultPage<DemoDTO> listPage(@Valid @RequestBody DemoListQuery query) {
        ResultPage<DemoDTO> resultPage;
        try {
            resultPage = demoService.listDemo(query);
        } catch (Throwable e) {
            e.printStackTrace();
            resultPage = new ResultPage<>(ResultConstant.FAILED);
            log.error("列表查询失败：{}", e.getMessage());
        }
        return resultPage;
    }

    @ApiOperation(value = "列表查询（树）", notes = "列表查询（树）", httpMethod = "POST", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @PostMapping(value = "/list/tree", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResultMsg<List<DataTree>> listTree(@Valid @RequestBody DemoListQuery query) {
        AuthenticationTokenDTO authenticationDTO = loginContext.getCurrentUser();
        ResultMsg<List<DataTree>> resultMsg;
        try {
            resultMsg = null;
        } catch (ApiException e) {
            e.printStackTrace();
            resultMsg = new ResultMsg<>(ResultConstant.FAILED, e.getMessage());
            log.error("列表（树）查询失败：{}", e.getMessage());
        } catch (Throwable e) {
            e.printStackTrace();
            resultMsg = new ResultMsg<>(ResultConstant.FAILED);
            log.error("列表（树）查询失败：{}", e.getMessage());
        }
        return resultMsg;
    }

    @GetMapping(value = "/find", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(value = "查询", httpMethod = "GET", notes = "根据id查询数据", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, example = "1", paramType = "query", dataType = "int"),
    })
    public ResultMsg<DemoDTO> find(@NotNull(message = "id不能为空") Integer id) {
        ResultMsg<DemoDTO> resultMsg;
        try {
            resultMsg = null;
        } catch (ApiException e) {
            e.printStackTrace();
            resultMsg = new ResultMsg<>(ResultConstant.FAILED, e.getMessage());
            log.error("查询失败：{}", e.getMessage());
        } catch (Throwable e) {
            e.printStackTrace();
            resultMsg = new ResultMsg<>(ResultConstant.FAILED);
            log.error("查询失败：{}", e.getMessage());
        }
        return resultMsg;
    }

    @ApiOperation(value = "新增", notes = "新增", httpMethod = "POST", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @PostMapping(value = "/add", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResultMsg<Integer> add(@Valid @RequestBody DemoSaveForm form) {
        ResultMsg<Integer> resultMsg = null;
        try {
            Integer id =demoService.addDemo(form);
            resultMsg = new ResultMsg<>(ResultConstant.SUCCESS,null,id);
        } catch (ApiException e) {
            e.printStackTrace();
            resultMsg = new ResultMsg<>(ResultConstant.FAILED, e.getMessage());
            log.error("新增失败：{}", e.getMessage());
        } catch (Throwable e) {
            e.printStackTrace();
            resultMsg = new ResultMsg<>(ResultConstant.FAILED);
            log.error("新增失败：{}", e.getMessage());
        }
        return resultMsg;
    }

    @GetMapping(value = "/delete", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(value = "删除", httpMethod = "GET", notes = "根据id删除数据", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, example = "1", paramType = "query", dataType = "int"),
    })
    public ResultMsg delete(@NotNull(message = "id不能为空") Integer id) {
        ResultMsg resultMsg;
        try {
            resultMsg = lock("demo_modify_"+id,()->{
                demoService.deleteSysUser(id);
                return new ResultMsg<>(ResultConstant.SUCCESS);
            });
        } catch (ApiException e) {
            e.printStackTrace();
            resultMsg = new ResultMsg<>(ResultConstant.FAILED, e.getMessage());
            log.error("删除失败：{}", e.getMessage());
        } catch (Throwable e) {
            e.printStackTrace();
            resultMsg = new ResultMsg<>(ResultConstant.FAILED);
            log.error("删除失败：{}", e.getMessage());
        }
        return resultMsg;
    }

    @ApiOperation(value = "文件上传", notes = "文件上传", httpMethod = "POST")
    @PostMapping(value = "upload", consumes = "multipart/*", headers = "content-type=multipart/form-data")
    public ResultMsg upload(HttpServletRequest request, @ApiParam(value = "上传的文件", required = true) MultipartFile file) {
        if (file.isEmpty()) {
            return new ResultMsg(ResultConstant.FAILED, "文件不能为空");
        }
        InputStream is = null;
        try {
            is = file.getInputStream();
            fileManager.upload(is,file.getOriginalFilename());
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return new ResultMsg(ResultConstant.SUCCESS, "文件" + file.getName() + "上传成功");
    }

    @GetMapping(value = "/download")
    @ApiOperation(value = "下载", httpMethod = "GET", notes = "下载")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, example = "1", paramType = "query", dataType = "int"),
    })
    public void download(@NotNull(message = "id不能为空") Integer id, HttpServletRequest request, HttpServletResponse response) {
        try {
            File file = new File("D:\\test.txt");
            if (!file.exists()) {
                file.createNewFile();
            }
            fileManager.download(response,file.getPath());
        } catch (ApiException e) {
            e.printStackTrace();
            log.error("下载失败：{}", e.getMessage());
        } catch (Throwable e) {
            e.printStackTrace();
            log.error("下载失败：{}", e.getMessage());
        }
    }
}
